<template>
  <div class="chat-view">

    <div class="chat-layout">
      <div class="history-container">
        <div class="history-header">
          <div class="header-left">
            <span>最近</span>
          </div>
          <el-dropdown>
            <el-icon><MoreFilled /></el-icon>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item>选择</el-dropdown-item>
                <el-dropdown-item  style="color: red;">清除所有会话</el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </div>
      <div class="chat-container">
        <div class="model-selector">
          <el-button type="primary" @click="handleNewChat">新会话</el-button>
          <el-button @click="showModelDialog = true">模型设置</el-button>
          <span v-if="selectedModel" class="current-model">当前模型: {{ getModelLabel() }}</span>
          <el-dialog v-model="showModelDialog" title="模型设置" width="30%">
            <el-form label-width="80px">
              <el-form-item label="供应商">
                <el-select v-model="selectedSupplier" placeholder="请选择供应商" @change="handleSupplierChange">
                  <el-option
                    v-for="supplier in suppliers"
                    :key="supplier.id"
                    :label="supplier.name"
                    :value="supplier.id"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="模型">
                <el-select v-model="selectedModel" placeholder="请选择模型">
                  <el-option
                    v-for="model in models"
                    :key="model.id"
                    :label="model.name"
                    :value="model.id"
                  />
                </el-select>
              </el-form-item>
              
              <el-form-item label="温度">
                <el-slider v-model="temperature" :min="0" :max="1" :step="0.1" />
              </el-form-item>
              <el-form-item label="上下文数">
                <el-slider v-model="contextLength" :min="1" :max="10" />
              </el-form-item>
            </el-form>
          </el-dialog>
        </div>
        <div class="messages">
          <div v-for="(message, index) in messages" :key="index" class="message" :class="message.role">
            <div v-html="renderMarkdown(message.content)"></div>
          </div>
        </div>
      
        <div class="input-area">
          <el-input
            v-model="inputMessage"
            placeholder="输入消息..."
            @keyup.enter="sendMessage"
          />
          <el-button type="primary" @click="sendMessage">发送</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { request } from '../../composables/useCommon';
import MarkdownIt from 'markdown-it';
import hljs from 'highlight.js';
import DOMPurify from 'dompurify';
import 'highlight.js/styles/github.css';
const showModelDialog = ref(false);
const selectedModel = ref('');
const inputMessage = ref('');
const messages = ref<Array<{role: string, content: string}>>([]);
const temperature = ref(0.7);
const contextLength = ref(4);


const models = ref<Array<{value: string, label: string}>>([]);
const selectedSupplier = ref('');
const suppliers = ref([]);

const handleNewChat = () => {
  messages.value = [];
};

const handleSupplierChange = (supplierId: string) => {
  const supplier = suppliers.value.find(s => s.id === supplierId);
  models.value = supplier ? supplier.child : [];
  selectedModel.value = '';
};

const fetchModels = async () => {
  try {
    const data = await request('ragModel/groupBySupplier','get');
    console.log('获取模型数据:', data);
    suppliers.value = data || [];
  } catch (error) {
    console.error('获取模型数据失败:', error);
  }
};


onMounted(() => {
  fetchModels();
});

const getModelLabel = () => {
  if (!selectedModel.value) return '';
  const model = models.value.find(m => m.id === selectedModel.value);
  return model ? model.modelName : '';
};

const md = new MarkdownIt({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(str, { language: lang }).value;
      } catch (__) {}
    }
    return '';
  }
});

const renderMarkdown = (content: string) => {
  const rendered = md.render(content);
  return DOMPurify.sanitize(rendered);
};



const sendMessage = async () => {
  if (!inputMessage.value.trim() || !selectedModel.value) return;

  if (messages.value.length === 0) {
    try {
      await request('ragSession/', 'POST', {
        descr: inputMessage.value
      });
    } catch (error) {
      console.error('创建会话错误:', error);
      return;
    }
  }
  
  messages.value.push({
    role: 'user',
    content: inputMessage.value
  });
  
  // 添加AI助手消息占位
  const assistantMessageIndex = messages.value.push({
    role: 'assistant',
    content: ''
  }) - 1;
  
  try {
    const response = await fetch('http://localhost:8889/ragModel/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        modelId: selectedModel.value,
        message: inputMessage.value,
        conversationId: '123',
        maxMessageSize: 10
      })
    });

    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      try {
// 由于 value 是 Uint8Array 类型，需要先解码为字符串再进行 JSON 解析
        const decodedValue = decoder.decode(value);

        
          // 匹配标准格式的JSON对象 [1]()
    const jsonRegex = /\{\s*"content"\s*:\s*"(?:[^"\\]|\\.)*"\s*\}/g;
    
    // 匹配所有符合格式的JSON字符串 [4]()
    const matches = decodedValue.match(jsonRegex)  || [];
    
    const result: Array<{ content: string }> = [];
    
    for (const match of matches) {
        try {
            // 解析单个JSON对象 [2]()
            const parsed = JSON.parse(match)  as { content: string };
            messages.value[assistantMessageIndex].content += parsed.content;
        } catch (e) {
            console.error(` 解析失败: ${match}`, e);
        }
    }
    



      
      } catch (e) {
        console.error('解析JSON失败:', e);
      }
    }
    
    inputMessage.value = '';
  } catch (error) {
    console.error('请求失败:', error);
  }
};
</script>

<style scoped>
.chat-view {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.chat-layout {
  display: flex;
  height: 100%;
}

.history-container {
  width: 12.66%;
  border: 1px solid #dcdfe6;
  background-color: white;
  margin: 10px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.history-header {
  font-weight: bold;
  margin-bottom: 10px;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}


.model-selector {
  margin: 10px;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
}

.current-model {
  font-size: 14px;
  color: #3d6bc7;
}

.chat-container {
  margin: 10px;
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  overflow: hidden;
  width: 87.33%;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.messages {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background-color: white;
}

.message {
  margin-bottom: 10px;
  padding: 8px;
  border-radius: 5px;
  font-size: 13px;
  max-width: fit-content;
  position: relative;
  box-shadow: 0 1px 3px rgba(90, 87, 87, 0.9)
}



.message.user {
  margin-left: auto;
  text-align: right;
}

.message.assistant {
  background-color: #e8e8e8;
  margin-right: auto;
  border-color: #e6e6e6;
  text-align: left;
}

/* Markdown代码块样式 */
.message :deep(pre) {
  background-color: #f6f8fa;
  border-radius: 6px;
  padding: 6px;
  overflow: auto;
  border: 1px solid #e1e4e8;
}

.message :deep(code) {
  font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  font-size: 14px;
  color: #24292e;
  background-color: rgba(27, 31, 35, 0.05);
  border-radius: 3px;
  padding: 0.2em 0.4em;
}

.message :deep(pre code) {
  background-color: transparent;
  padding: 0;
}

.input-area {
  display: flex;
  padding: 20px;
  border-top: 1px solid #eee;
  gap: 10px;
}

.input-area .el-input {
  flex: 1;
}

.input-area .el-input :deep(.el-textarea__inner) {
  min-height: 100px;
}
</style>